///************************************************************************
/// <copyrigth>2018-2019 Corporation.All Rights Reserved</copyrigth>
/// <author>tangyingzhong</author>
/// <contact>tangyz114987@outlook.com</contact>
/// <version>v1.0.0</version>
/// <describe>
/// It is an event base for solving firing and listening events
///</describe>
/// <date>2019/12/11</date>
///***********************************************************************
#ifndef EVENTBASE_H
#define EVENTBASE_H

#include <memory>
#include "EventHandler/EventHandler.h"
#include "IEventBase.h"

namespace SystemTool
{
	template<class T1 = IEventBase, class T2 = EventArgs>
	class EventBase :public T1
	{
	public:
		typedef IEventBase::HandlerFunc HandlerFunc;

	public:
		// Construct the EventBase
		EventBase() :m_bDisposed(false)
		{
			Initialize();
		}

	protected:
		// Detructe the EventBase
		virtual ~EventBase()
		{
			if (!GetDisposed())
			{
				SetDisposed(true);

				Destory();
			}
		}

	public:
		// Listen plugins
		virtual bool Listen(void* pListener,
			HandlerFunc pListenHandler,
			int iEventID)
		{
			std::shared_ptr<HandlerFunc> pFunc = std::make_shared<HandlerFunc>(pListenHandler);

			return m_EventHandler.RegisterEvent(pListener, iEventID, pFunc);
		}

		// Listen to the object
		virtual bool UnListen(void* pListener,
			HandlerFunc pListenHandler,
			int iEventID)
		{
			std::shared_ptr<HandlerFunc> pFunc = std::make_shared<HandlerFunc>(pListenHandler);

			return m_EventHandler.UnRegisterEvent(pListener, iEventID, pFunc);
		}

		// UnListen receiver
		virtual bool UnListen(void* pListener)
		{
			return m_EventHandler.UnRegisterEvent(pListener);
		}

		// UnListen receiver's event id
		virtual bool UnListen(void* pListener, int iEventID)
		{
			return m_EventHandler.UnRegisterEvent(pListener, iEventID);
		}

		// UnListen to event id
		virtual bool UnListen(int iEventID)
		{
			return m_EventHandler.UnRegisterEvent(iEventID);
		}

		// UnListen to event id's handler function
		virtual bool UnListen(int iEventID, HandlerFunc pListenHandler)
		{
			std::shared_ptr<HandlerFunc> pFunc = std::make_shared<HandlerFunc>(pListenHandler);

			return m_EventHandler.UnRegisterEvent(iEventID, pFunc);
		}

		// UnListen to the handler function
		virtual bool UnListen(HandlerFunc pListenHandler)
		{
			std::shared_ptr<HandlerFunc> pFunc = std::make_shared<HandlerFunc>(pListenHandler);

			return m_EventHandler.UnRegisterEvent(pFunc);
		}

	protected:
		// Notidy all listeners who listening this event id
		void Notify(void* pNotifier, int iEventID, T2* pArgs)
		{
			m_EventHandler.FireEvent(pNotifier, iEventID, pArgs);
		}

	private:
		// Initialize the EventBase
		void Initialize(){	}

		// Destory the EventBase
		void Destory(){	}

	private:
		// Get the disposed status
		inline bool GetDisposed() const
		{
			return m_bDisposed;
		}

		// Set the disposed status
		inline void SetDisposed(bool bDisposed)
		{
			m_bDisposed = bDisposed;
		}

	private:
		// Event handler container
		EventHandler m_EventHandler;

		// Disposed status
		bool m_bDisposed;
	};
}

#endif // EVENTBASE_H
